package com.service.business.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.service.business.order.service.OrderProductHrComboService;
import com.service.business.product.controller.rep.ProductHrComboDetailRep;
import com.service.business.product.controller.rep.ProductHrComboPageRep;
import com.service.business.product.controller.rep.ProductPayTypeRep;
import com.service.business.product.service.ProductHrComboService;
import com.service.business.product.service.ProductPayTypeService;
import com.service.business.support.Language;
import com.service.business.support.SessionUtil;
import com.service.business.utils.DateUtil;
import com.service.core.exception.CommonException;
import com.service.core.rest.request.PageRequest;
import com.service.core.rest.response.CommonPageRep;
import com.service.dao.enums.CommonStatusEnums;
import com.service.dao.mapper.CoinsMapper;
import com.service.dao.mapper.ProductHrComboMapper;
import com.service.dao.model.Coins;
import com.service.dao.model.ProductHrCombo;
import com.service.utility.modelmapper.ModelMapperUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


@Service("hashRateComboService")
public class ProductHrComboServiceImpl extends ServiceImpl<ProductHrComboMapper, ProductHrCombo> implements ProductHrComboService {

    @Autowired
    private SessionUtil sessionUtil;

    @Autowired
    private ProductPayTypeService productPayTypeService;

    @Autowired
    private OrderProductHrComboService orderProductHrComboService;

    @Autowired
    private CoinsMapper coinsMapper;

    @Override
    public CommonPageRep<ProductHrComboPageRep> pageCombo(Integer coinsId, Integer comboType, PageRequest pageRequest) {

        Page<ProductHrCombo> page = PageHelper.startPage(pageRequest.getPageNo(), pageRequest.getPageSize());
//        list(new QueryWrapper<ProductHrCombo>().lambda()
//                .eq(ProductHrCombo::getLanguage, Language.LANG.get())
//                .eq(ProductHrCombo::getCoinsId,coin.getCode())
//                .eq(ProductHrCombo::getComboType,comboType.getCode())
//                .eq(ProductHrCombo::getComboStatus, CommonStatusEnums.ACTIVE.getCode()));


        Coins coins = coinsMapper.selectOne(new LambdaQueryWrapper<Coins>().eq(Coins::getId, coinsId));
        List<ProductHrCombo> productHrCombos = baseMapper.pageList(coins.getCoinName(), null, comboType, CommonStatusEnums.ACTIVE.getCode());


        Date tomorrow = DateUtil.addDay(new Date(), 1);
        List<ProductHrComboPageRep> resultList = productHrCombos.stream().map(item -> this.buildHrComboPageRep(item, tomorrow)).collect(Collectors.toList());
        return CommonPageRep.buildResultRep(page, resultList);

    }

    @Override
    public CommonPageRep<ProductHrComboPageRep> pagePopularCombo(PageRequest request) {
        Page<ProductHrCombo> page = PageHelper.startPage(request.getPageNo(), request.getPageSize());
        list(new QueryWrapper<ProductHrCombo>().lambda().eq(ProductHrCombo::getLanguage, Language.LANG.get())
                .eq(ProductHrCombo::getIsPopularize, CommonStatusEnums.ACTIVE.getCode())
                .eq(ProductHrCombo::getComboStatus, CommonStatusEnums.ACTIVE.getCode())
                .orderByDesc(ProductHrCombo::getCreateTime));
        Date tomorrow = DateUtil.addDay(new Date(), 1);
        List<ProductHrComboPageRep> resultList = page.getResult().stream().map(item -> this.buildHrComboPageRep(item, tomorrow)).collect(Collectors.toList());
        return CommonPageRep.buildResultRep(page, resultList);
    }

    @Override
    public ProductHrComboDetailRep detail(Integer comboId) {
        ProductHrCombo combo = baseMapper.selectById(comboId);
        if (ObjectUtils.isEmpty(combo)) {
            throw new CommonException("不存在此套餐", "hash_rate_combo_not_exist");
        }

        if (!ObjectUtils.isEmpty(combo.getLimitBuyNum()) && combo.getLimitBuyNum() > 0) {
            Integer memberId = sessionUtil.getUser().getUserId();
            Integer totalOrderCount = orderProductHrComboService.totalEffectiveOrderByMemberIdAndComboId(memberId, combo.getId());
            if (totalOrderCount >= combo.getLimitBuyNum()) {
                throw new CommonException("已达到该产品限购数量", "hash_rate_combo_limit_num");
            }
        }
        Date tomorrow = DateUtil.addDay(new Date(), 1);
        return buildHrComboDetailRep(combo, tomorrow);
    }


    /**
     * pageRep
     *
     * @param combo
     * @param tomorrow
     * @return
     */
    private ProductHrComboPageRep buildHrComboPageRep(ProductHrCombo combo, Date tomorrow) {
        ProductHrComboPageRep detailRep = ModelMapperUtil.getStrictModelMapper().map(combo, ProductHrComboPageRep.class);
        detailRep.setBuyNum(combo.getFakeBuyNum());
        detailRep.setStartMiningTime(DateUtil.nDaysAfterDate(combo.getPackageDays()));
        List<ProductPayTypeRep> list = productPayTypeService.listByOrderType(combo.getComboType());
        detailRep.setComboPriceCoin(list.get(0).getPayName());
        return detailRep;
    }

    /**
     * detailRep
     *
     * @param combo
     * @param tomorrow
     * @return
     */
    private ProductHrComboDetailRep buildHrComboDetailRep(ProductHrCombo combo, Date tomorrow) {
        ProductHrComboDetailRep detailRep = ModelMapperUtil.getStrictModelMapper().map(combo, ProductHrComboDetailRep.class);
        detailRep.setBuyNum(combo.getFakeBuyNum());
        detailRep.setStartMiningTime(DateUtil.nDaysAfterDate(combo.getPackageDays()));
        List<ProductPayTypeRep> list = productPayTypeService.listByOrderType(combo.getComboType());
        detailRep.setComboPriceCoin(list.get(0).getPayName());
        return detailRep;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void updateProductStockNum(Integer productId, Integer sellNum) {
        ProductHrCombo productHrCombo = getById(productId);

        ProductHrCombo updateHrCombo = new ProductHrCombo();
        updateHrCombo.setId(productHrCombo.getId());
        updateHrCombo.setBuyNum(productHrCombo.getBuyNum() + sellNum);
        updateHrCombo.setFakeBuyNum(productHrCombo.getFakeBuyNum() + sellNum);
        updateHrCombo.setStock(productHrCombo.getStock() - sellNum);

        updateById(updateHrCombo);
    }
}
